package com.zzy.service.impl;

import cn.hutool.core.io.IoUtil;
import com.zzy.service.ActivityConsumerService;
import com.zzy.util.UtilDiagrams;
import org.activiti.engine.*;
import org.activiti.engine.repository.DeploymentBuilder;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.*;

@Service
public class ActivityConsumerServiceImpl implements ActivityConsumerService {

    @Resource
    private ProcessEngine processEngine;
    @Resource
    private RepositoryService repositoryService;
    @Resource
    private RuntimeService runtimeService;
    @Resource
    private TaskService taskService;
    @Resource
    private HistoryService historyService;

    public String  getVersion(){
        return ProcessEngine.VERSION;
    }


    @Override
    public List getFlowBpmnList() {
        List list = new ArrayList();
        String deployList[] = UtilDiagrams.list();
        if(deployList.length>0){
            for(String dep : deployList){
                Map map = new HashMap();
                String name = dep.substring(0  , dep.lastIndexOf(".") );
                map.put("name",name);
                map.put("type","bpmn");//因为都是 bpmn 文件
                map.put("fullName",dep);
                list.add(map);
            }
        }
        return list;
    }

    /**
     * 部署流程
     * 部署完流程，会在这几个表中生成数据
     * act_re_deployment
     * act_ge_bytearray
     * act_re_procdef
     * */
    public Integer deployFlow(String processName){
        //要判断，是否已经部署，如果已经部署， 部署的流程是否已经结束， 删除还是保留，都是问题
        RepositoryService service = processEngine.getRepositoryService();
        DeploymentBuilder build= service.createDeployment();
        if (null != processName) {
            // 直接部署  注意路径
            build.addClasspathResource("processes/"+processName);
            build.deploy();
           /* if(processName.equals("Bxsp.bpmn")){
                service.createDeployment().addClasspathResource("diagrams/" + processName)
                        .addClasspathResource("form/bxsp.form")
                        .deploy();
            }else if(processName.equals("Hello.bpmn")){//请假表单
                service.createDeployment().addClasspathResource("diagrams/" + processName)
                        .addClasspathResource("form/qingjia.form")
                        .addClasspathResource("form/qingjia_audit.form")
                        .deploy();
            }else{
                service.createDeployment().addClasspathResource("diagrams/" + processName).deploy();
            }*/
        }
        return 0;
    }


    /** 已经 部署的 流程   */
    public List<Map<String,Object>> getDeployedList(){
        List<Map<String,Object>> list = new LinkedList<>();

        List<ProcessDefinition> plist = repositoryService.createProcessDefinitionQuery().list();
        plist.forEach(  p  -> {
            Map<String,Object> map = new HashMap<>();
            map.put("id",p.getId());
            map.put("category",p.getCategory());
            map.put("name",p.getName());
            map.put("key",p.getKey());
            map.put("description",p.getDescription());
            map.put("version",p.getVersion());
            map.put("resourceName",p.getResourceName());
            map.put("deploymentId",p.getDeploymentId());
            map.put("diagramResourceName",p.getDiagramResourceName());
            map.put("hasStartFormKey",p.hasStartFormKey());
            map.put("hasGraphicalNotation",p.hasGraphicalNotation());
            map.put("isSuspended",p.isSuspended());
            map.put("tenantId",p.getTenantId());
            map.put("engineVersion",p.getEngineVersion());
            list.add(map);
        });

        return list;
    }

    @Override
    public String startFlow() {
        return null;
    }

    @Override
    public String cancalStartedFlow() {
        return null;
    }

    @Override
    public String getFlowTask() {
        return null;
    }

    @Override
    public String completeTask() {
        return null;
    }

    @Override
    public String revertTask() {
        return null;
    }

    /**取消部署流程*/
    public String cancalDeployFlow(String processDefinitionId){

        //判断是否 流程 已经执行
        RepositoryService service = processEngine.getRepositoryService();
        String state = "";
        try {
            //根据 流程 ID 获取当前流程
            ProcessDefinition processDefinition = service.createProcessDefinitionQuery()
                    .processDefinitionId(processDefinitionId).singleResult();
            //查询该流程是否已经，启动任务,如果忽略启动，可采取
            service.deleteDeployment(processDefinition.getDeploymentId(),true);
            //方式删除
            //如果流程 已经启动会生成 一个task
            /*
            // 这种 方法 采用循环 数量大的 情况下 不可取
            List<Task> taskList = engine.getTaskService().createTaskQuery().list();
            for(Task t : taskList){
                if (t.getProcessDefinitionId().equals(id)){//说明 该流程已经启动
                    break;
                }
            }*/
            /*List list = utilService.getListBySql("select ID_ from act_ru_task where PROC_DEF_ID_ ='"+id+"'");
            if(list!=null && list.size()>0){//流程已经启动 ， 不可以删除
                if(flag!=null && "qz".equals(flag)){//强制删除
                    service.deleteDeployment(processDefinition.getDeploymentId(),true);//强制 级联删除
                    state = "已经清除相关启动的流程，并且取消部署!";
                }else {
                    state = "该流程已经启动，不能撤回！";
                }
            }else{//说明 流程没有启动可以删除
                state = "已经取消部署!";
                service.deleteDeployment(processDefinition.getDeploymentId());
            }*/
            //service.deleteDeployment(processDefinition.getDeploymentId());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return state;
    }





    public ResponseEntity getGraphics(String processDefinitionId,String resType){
        HttpHeaders headers = new HttpHeaders();
        if ("xml".equals(resType)) {//xml格式
            headers.setContentType(MediaType.APPLICATION_XML);
        } else {//image 图片格式
            headers.setContentType(MediaType.IMAGE_PNG);
        }
        //获取流程定义信息
        ProcessDefinition processDefinition = repositoryService
                .createProcessDefinitionQuery()
                .processDefinitionId(processDefinitionId)
                .singleResult();
        String resourceName = "";
        if ("image".equals(resType)) {
            resourceName = processDefinition.getDiagramResourceName();
        } else if ("xml".equals(resType)) {
            resourceName = processDefinition.getResourceName();
        }
        InputStream resourceAsStream = repositoryService
                .getResourceAsStream(processDefinition.getDeploymentId(), resourceName);
        /*  <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>4.5.16</version>
        </dependency>*/
        return new ResponseEntity(IoUtil.readBytes(resourceAsStream), headers, HttpStatus.CREATED);
    }


    /**
     * 删除所有流程信息【慎用】
     */
    public void clearAllData(HttpServletResponse response) {
	/*
		Task task = engine.getTaskService().createTaskQuery().taskId(taskId).singleResult();
		TaskService service1=engine.getTaskService();
		RuntimeService service2 = engine.getRuntimeService();
        List list1 = service.createModelQuery().list();
        List list2 = service.createProcessDefinitionQuery().list();//获取流程
        List list3 = service.createDeploymentQuery().list();//部署信息
        RuntimeService service2 = engine.getRuntimeService();
        List list01 = service2.createProcessInstanceQuery().list();//启动流程后的关联表
        List list02 = service2.createExecutionQuery().list();
		*/
        //后期 可以把 这个 删除 语句 放到 存储 过程去,直接调用 一个sql就行了
        String tables[] = {
                "act_evt_log","act_ge_property", "act_procdef_info",
                "act_ge_bytearray","act_hi_actinst","act_hi_comment",
                "act_hi_detail","act_hi_identitylink","act_hi_procinst",
                "act_hi_taskinst","act_hi_varinst","act_re_deployment",
                "act_re_model","act_ru_identitylink","act_ru_event_subscr",
                 "act_ru_variable","act_ru_job",
                "act_ru_deadletter_job","act_ru_integration","act_ru_suspended_job","act_ru_timer_job",
                "act_ru_task","act_ru_execution","act_re_procdef",
                "act_hi_attachment"
        };
        for(String table : tables){
            String sql ="DELETE FROM " + table ;
           // utilService.executeSql(sql);
        }
    }

}
